<script lang="ts" setup>
import { Form, Input, Select, TabPane, Tooltip, Button, Drawer, Textarea, message, Switch, InputNumber, Row, Col } from 'ant-design-vue'
import {
    type IMixCaseStep,
    type IMixCaseStepAssertion,
    type IMixCaseStepRelation,
    type IMixConstantSelectOptions,
    defaultWithIMixCaseStepAssertion,
    defaultWithIMixCaseStepRelation,
} from '~/types/apis/mix-case'
import type RequestConfigVue from './RequestConfig.vue'
import type FormItemProxyVue from '~/components/FormItem/FormItemProxy.vue'
import type { ComponentExposed } from 'vue-component-type-helpers'
import { ref, watch } from 'vue';
import type { DrawerProps } from 'ant-design-vue';
import type { AfterFetchContext } from '@vueuse/core'
import type { IBasic } from '~/types/apis/basic'
import type { IProxy } from '~/types/apis/proxy';


defineProps<{
    mixConstantSelectOptions: IMixConstantSelectOptions
}>()
const selectedStep = defineModel<IMixCaseStep>('selectedStep', {
    required: true,
})

const globalConfig = useGlobalConfigStore()

const requestConfigRef = ref<ComponentExposed<typeof RequestConfigVue>>()

const columnsWithAssertion: ColumnsType<any> = [
    { title: '断言来源', dataIndex: 'from', key: 'from' },
    { title: '断言类型', dataIndex: 'type', key: 'type' },
    { title: '断言动作', dataIndex: 'action', key: 'action' },
    { title: '关联表达式', dataIndex: 'express', key: 'express' },
    { title: '预期值', dataIndex: 'value', key: 'value' },
    { title: '操作', dataIndex: 'operator', key: 'operator', width: 200 },
]
const dataSourceWithAssertion = ref<IMixCaseStepAssertion[]>([])

const columnsWithRelation: ColumnsType<any> = [
    { title: '关联来源', dataIndex: 'from', key: 'from' },
    { title: '关联类型', dataIndex: 'type', key: 'type' },
    { title: '关联表达式', dataIndex: 'express', key: 'express' },
    { title: '关联变量名', dataIndex: 'name', key: 'name' },
    { title: '操作', dataIndex: 'operator', key: 'operator', width: 200 },
]
const dataSourceWithRelation = ref<IMixCaseStepRelation[]>([])

async function deserialize() {
    await nextTick()

    dataSourceWithRelation.value = objectDeserializer(
        selectedStep.value.relation,
        true,
    )
    dataSourceWithAssertion.value = objectDeserializer(
        selectedStep.value.assertion,
        true,
    )
    requestConfigRef.value!.deserialize({
        query: selectedStep.value.query,
        header: selectedStep.value.header,
        rest: selectedStep.value.rest,
        body: selectedStep.value.body,
        bodyType: selectedStep.value.bodyType,
    })
}

function serialize() {
    selectedStep.value.relation = objectSerializer(dataSourceWithRelation.value)
    selectedStep.value.assertion = objectSerializer(dataSourceWithAssertion.value)
    const { body, header, query, rest } = requestConfigRef.value!.serialize()
    selectedStep.value.body = body
    selectedStep.value.rest = rest
    selectedStep.value.query = query
    selectedStep.value.header = header
}

watch(
    selectedStep,
    async () => {
        await deserialize()
    },
    { deep: true, immediate: true },
)

const formCurl = reactive({
    curl: '',
})

//  弹出curl部分的script
const placement = ref<DrawerProps['placement']>('left');
const open = ref<boolean>(false);

const showDrawer = () => {
    open.value = true;
};

const onClose = () => {
    open.value = false;
};

const { post } = useCustomFetch(`/engine-service/api/v1/api_case_step/curlParser`, {
    immediate: false,
    afterFetch(ctx: AfterFetchContext<IBasic<any>>) {
        if (ctx.data && ctx.data.code === 0) {

            selectedStep.value.path = ''
            selectedStep.value.method = ''
            selectedStep.value.body = ''
            selectedStep.value.query = ''
            selectedStep.value.header = ''


            selectedStep.value.path = ctx.data.data.path
            selectedStep.value.method = ctx.data.data.method
            selectedStep.value.body = ctx.data.data.body
            selectedStep.value.bodyType = ctx.data.data.bodyType
            selectedStep.value.query = ctx.data.data.query
            selectedStep.value.header = ctx.data.data.header
            open.value = false;
            // alert(JSON.stringify(ctx.data.data))
        }

        return ctx
    },
})


const subCurl = async () => {
    if (formCurl.curl.trim() === '') {
        message.error('请输入正确的cURL地址：')
        return
    }
    await post(formCurl).execute()

}
defineExpose({ serialize })

/**
 * 重试开关变动
 */
let isRetrySwitchType = ref(!globalConfig.selectedStep.isRetry);
watch(() => globalConfig.selectedStep.isRetry,
    (newValue) => {
        if (newValue) {
            isRetrySwitchType.value = false
        } else {
            isRetrySwitchType.value = true
        }
    },
    { deep: true }
)

const formItemProxyRef = ref<ComponentExposed<typeof FormItemProxyVue>>()
/**
 * 代理开关变动
 */
watch(() => selectedStep.value.startProxy,
    (newValue) => {
        if (!newValue) {
            selectedStep.value.proxyId = null
        } else {
            // 当用户开启开关时默认选择第一个代理
            if (selectedStep.value.proxyId == null) {
                const refData = formItemProxyRef.value!.proxiesData as IProxy[]
                selectedStep.value.proxyId = Number(refData[0].id)
            }

        }
    },
    { deep: true }
)
</script>


<template>
    <!-- rURL的弹窗 -->
    <Button type="primary" @click="showDrawer">import cURL(bash)</Button>
    <Drawer size="large" title="cURL:" :placement="placement" :closable="false" :open="open" @close="onClose">
        <Form :model="formCurl">
            <Form.Item>
                <Textarea style="height: 500px; width: 800px" v-model:value="formCurl.curl" placeholder="请输入名称" />
            </Form.Item>
            <Form.Item>
                <Button type="primary" @click="subCurl">提交</Button>
            </Form.Item>
        </Form>
    </Drawer>

    <!-- 主体部分 -->
    <div my-6>

        <Form :model="selectedStep">
            <Form.Item label="用例名称：">
                <Input v-model:value="selectedStep.name" placeholder="请输入名称" />
            </Form.Item>
            <Form.Item label="用例描述：">
                <Input.TextArea v-model:value="selectedStep.description" placeholder="请输入名称" />
            </Form.Item>
            <Row :gutter="27">
                <Col :span="12">
                <Form.Item label="引擎类型" >
                    <Input v-model:value="selectedStep.engineType" disabled />
                </Form.Item>
                </Col>
                <Col :span="12">
                <FormItemMethod v-model:method="selectedStep.method" :disabled="operatorDisabled"
                    :differentFields="differentFields" />
                </Col>
            </Row>
            <Row :gutter="27">
                <Col :span="12">
                <Form.Item label="接口地址：" >
                    <Input v-model:value="selectedStep.path" placeholder="请输入接口地址" :disabled="operatorDisabled" />
                </Form.Item>
                </Col>
                <Col :span="12">
                <FormItemLevel v-model:level="selectedStep.level" :disabled="operatorDisabled"
                    :differentFields="differentFields" />
                </Col>
            </Row>
            <Row :gutter="27">
                <Col :span="12">
                <FormItemEnvironment v-model:environment-id="selectedStep.environmentId" :disabled="operatorDisabled"
                    :differentFields="differentFields" />

                </Col>
                <Col :span="12">
                <Form.Item label="重试类型">
                    <Select v-model:value="selectedStep.retryType" :disabled="true">
                        <Select.Option value="同步">同步重试</Select.Option>
                        <Select.Option value="异步">异步重试</Select.Option>
                    </Select>
                </Form.Item>
                </Col>
            </Row>

            <Row :gutter="30">
                <Col :span="8">
                <Form.Item label="重试次数">
                    <InputNumber v-model:value="selectedStep.retryCount"
                        :disabled="isRetrySwitchType || operatorDisabled" style="width: 100%;" />
                </Form.Item>
                </Col>
                <Col :span="10">
                <Form.Item label="首次重试间隔(单位: 秒 )"
                   >
                    <InputNumber v-model:value="selectedStep.retryFirstInterval" :disabled="isRetrySwitchType" style="width: 100%;"/>
                </Form.Item>
                </Col>
                <Col :span="6">
                <Form.Item label="失败是否重试(默认关闭)">
                    <Switch v-model:checked="selectedStep.isRetry" :disabled="operatorDisabled" />
                </Form.Item>
                </Col>
            </Row>

            <Row :gutter="30">
               
                <Col :span="8">
                <FormItemProxy :disabled="selectedStep.startProxy" v-model:proxy-id="selectedStep.proxyId"
                    :differentFields="differentFields" ref="formItemProxyRef" />
                </Col>
                <Col :span="8">
                <Form.Item label="是否开启代理(默认关闭)" >
                    <Switch v-model:checked="selectedStep.startProxy" :disabled="operatorDisabled" />
                </Form.Item>
                </Col>
            </Row>
            <!-- <Form.Item label="引擎类型">
                <Input v-model:value="selectedStep.engineType" disabled />
            </Form.Item>
            <FormItemMethod v-model:method="selectedStep.method" />
            <Form.Item label="接口地址：">
                <Input v-model:value="selectedStep.path" placeholder="请输入接口地址" />
            </Form.Item>

            <FormItemLevel v-model:level="selectedStep.level" />

            <FormItemEnvironment v-model:environment-id="selectedStep.environmentId" />
            <Form.Item label="重试类型">
                <Select v-model:value="selectedStep.retryType" :disabled="true">
                    <Select.Option value="同步">同步重试</Select.Option>
                    <Select.Option value="异步">异步重试</Select.Option>
                </Select>
            </Form.Item>

            <Form.Item label="重试次数">
                <InputNumber v-model:value="selectedStep.retryCount" :disabled="isRetrySwitchType" />
            </Form.Item>

            <Form.Item label="首次重试间隔(单位: 秒 )">
                <InputNumber v-model:value="selectedStep.retryFirstInterval" :disabled="isRetrySwitchType" />
            </Form.Item>

            <div flex="~ justify-between">
                <div flex="~ justify-between" style="width: 50%;">
                    <Form.Item label="是否开启代理(默认关闭)">
                        <Switch v-model:checked="selectedStep.startProxy" />
                    </Form.Item>
                    <FormItemProxy :disabled="selectedStep.startProxy" v-model:proxy-id="selectedStep.proxyId"
                        ref="formItemProxyRef" />
                </div>
                <Form.Item label="失败是否重试(默认关闭)">
                    <Switch v-model:checked="selectedStep.isRetry" />
                </Form.Item>
            </div> -->
        </Form>

        <RequestConfig ref="requestConfigRef" v-model:body-type="selectedStep.bodyType">
            <template #foot>
                <TabPane key="relation" tab="关联变量">
                    <EditableTable v-model:data-source-proxy="dataSourceWithRelation" :custom-fields="['from', 'type']"
                        :columns="columnsWithRelation" @add-data="
                            dataSourceWithRelation.push({
                                ...defaultWithIMixCaseStepRelation,
                            })
                            ">
                        <template #bodyCell="{ column, isEdit, currentEditableInstance }">
                            <template v-if="isEdit && column.key === 'from'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in mixConstantSelectOptions.mix_relate_field_from"
                                        :key="item.id" :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>

                            <template v-if="isEdit && column.key === 'type'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in mixConstantSelectOptions.mix_relate_type" :key="item.id"
                                        :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>
                        </template>
                    </EditableTable>
                </TabPane>
                <TabPane key="assertion" tab="断言">
                    <EditableTable v-model:data-source-proxy="dataSourceWithAssertion"
                        :custom-fields="['from', 'type', 'action']" :columns="columnsWithAssertion" @add-data="
                            dataSourceWithAssertion.push({
                                ...defaultWithIMixCaseStepAssertion,
                            })
                            ">
                        <template #bodyCell="{ column, isEdit, currentEditableInstance }">
                            <template v-if="isEdit && column.key === 'from'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in mixConstantSelectOptions.mix_assert_field_from"
                                        :key="item.id" :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>

                            <template v-if="isEdit && column.key === 'type'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in mixConstantSelectOptions.mix_assert_type" :key="item.id"
                                        :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>

                            <template v-if="isEdit && column.key === 'action'">
                                <Select v-model:value="currentEditableInstance[column.key!]">
                                    <Select.Option v-for="item in mixConstantSelectOptions.mix_assert_action" :key="item.id"
                                        :value="item.value">
                                        <Tooltip :title="item.remark">
                                            {{ item.name }}
                                        </Tooltip>
                                    </Select.Option>
                                </Select>
                            </template>
                        </template>
                    </EditableTable>
                </TabPane>
            </template>
        </RequestConfig>
    </div>
</template>
